import React from 'react';
import PropTypes from 'prop-types';
import css from './index.less';
import Icon from 'components/icon';
import { findSimulator } from 'common/utils/store';
import { stringExtendStyle } from 'common/utils/style';
import { observer } from 'mobx-react';
import { computed } from 'mobx';
import Utils from 'common/utils/index.js';

const { addEvent, removeEvent } = Utils;
const DIST = 20;
const SIZE = 18;
@observer
export default class Rotate extends React.Component {
  static propTypes = {
    mod: PropTypes.object.isRequired,
  };

  startX = 0;
  startY = 0;
  originX = 0;
  originY = 0;
  simulator = null;

  constructor(props) {
    super(props);
    this.state = {};
    this.rotate = 0;  // 旋转角度
  }

  componentDidMount() {
    this.onMouseMove = this.onMouseMove.bind(this);
    this.onMouseUp = this.onMouseUp.bind(this);
    const { mod } = this.props;
    this.simulator = findSimulator(mod);
  }

  componentWillUnmount() {
    this.detachEvent();
  }

  detachEvent() {
    removeEvent(document, 'mousemove', this.onMouseMove);
    removeEvent(document, 'mouseup', this.onMouseUp);
    removeEvent(document, 'mouseleave', this.onMouseUp);
  }

  @computed get style() {
    const { mod, mod: { rect: { width, height, left, top }, rotate } } = this.props;
    const { scrollTop } = findSimulator(mod);
    return {
      left: left - SIZE / 2 + width / 2,
      top: top + height - scrollTop + DIST,
      transform: stringExtendStyle([
        {
          key: 'rotate',
          val: rotate
        }
      ]),
      transformOrigin: `${SIZE / 2}px -${parseInt(height / 2) + DIST}px`,
    };

  }

  @computed get lineStyle() {
    return {
      left: SIZE / 2,
      top: -DIST,
      height: DIST + 2,
    };
  }

  onMouseMove(e) {
    const { mod } = this.props;
    e.stopPropagation();
    e.preventDefault();

    let movingRad = Math.atan2(e.pageY - this.originY, e.pageX - this.originX);
    movingRad -= Math.atan2(this.startY - this.originY, this.startX - this.originX);

    let deg = movingRad * (360 / (2 * Math.PI)) + this.rotate;
    deg = deg < 0 ?
      360 + deg : deg > 360 ?
        deg - 360 : deg;
    mod.update('rotate', parseInt(deg));
  }
  onMouseUp(e) {
    e.stopPropagation();
    e.preventDefault();
    this.detachEvent();
  }

  render() {
    const props = {
      className: css.rotate,
      style: this.style,
      onMouseDown: (e) => {
        e.preventDefault();
        e.stopPropagation();
        const { mod, mod: { rect: { width, height, left, top } } } = this.props;
        const { scrollTop } = this.simulator;
        this.rotate = mod.rotate;
        this.originX = left + (width / 2);
        this.originY = top + DIST + (height / 2) - scrollTop;
        this.startX = e.pageX;
        this.startY = e.pageY;

        addEvent(document, 'mousemove', this.onMouseMove);
        addEvent(document, 'mouseup', this.onMouseUp);
        addEvent(document, 'mouseleave', this.onMouseUp);
      }
    };
    const iconProps = {
      type: 'icon-rotate',
      style: {
        fontSize: SIZE,
      }
    };
    const lineProps = {
      className: css.line,
      style: this.lineStyle
    };
    return (
      <div {...props}>
        <Icon {...iconProps} />
        <div {...lineProps} />
      </div>
    );
  }
}
